﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CW.Bll.TrafficVideoGather.GatherClient
{




    public class DS40SdkApi
    {
        #region 结构体

        public struct DS_BOARD_DETAIL
        {
            BOARD_TYPE_DS type;//；板卡型号
            byte[] sn;//；序列号
            int dspCount;//；此张板卡所包含的 DSP 个数
            int firstDspIndex;//；此张板卡上第一个 DSP 在所有 DSP 中的索引
            int encodeChannelCount;//；此张板卡所包含的编码通道个数
            int firstEncodeChannelIndex;//；此张板卡上第一个编码通道在所有编码通道中的索引
            int decodeChannelCount; //；此张板卡所包含的解码通道个数
            int firstDecodeChannelIndex;//；此张板卡上第一个解码通道在所有解码通道中的索引
            int displayChannelCount;//；此张板卡所包含的显示通道个数
            int firstDisplayChannelIndex;//；此张板卡上第一个显示通道在所有显示通道中的索引
            int reserved1;//；
            int reserved2;//；
            int initInfo;//； 初始化信息，格式：初始化是否失败标志位:bit31,为 1 表示失败，为 0 表示成功；插槽
            //号为 0； 总线号:bit 8-15；设备号:bit0-7，板卡没有设备号，因此设备号为 0
            int version; //； 硬件版本，格式： major.minor.build， major:bit 16-19， minor:bit8-15， build:0-7
        }

        public enum BOARD_TYPE_DS
        {
            DS4004HC = 2,		//4004HC
            DS4008HC = 3,		//4008HC
            DS4016HC = 4,		//4016HC
            DS4001HF = 5,		//4001HF
            DS4004HF = 6,		//4004HF
            DS4002MD = 7,		//4002MD
            DS4004MD = 8,		//4004MD
            DS4016HCS = 9,		//4016HCS
            DS4004HC_PLUS = 13,	//4004HC+
            DS4008HC_PLUS = 14,	//4008HC+
            DS4016HC_PLUS = 15,	//4016HC+
            DS4008HF = 16,	//4008HF
            DS4008MD = 17,	//4008MD
            DS4008HS = 18,	//4008HS
            DS4016HS = 19,	//4016HS

            DS4108HCV = 20,	//4108HCV
            DS4116HCV = 21,	//4116HCV
            DS5016HC = 22,    //5016HC

            DS4208HFV = 23,    //4208HFV
            DS4216HC = 24,    //4216HC
            DS4216HFV = 25,    //4216HFV

            DS5008HF = 26,    //5008HF
            DS5116HF = 27,    //5116HF

            DS5216HC = 28,	//5216HC
            DS5208HF = 29,	//5208HF
            DS5216HF = 30,	//5216HF

            DS4101HD = 31,	//4101HD
            DS4102HD = 32,	//4102HD
            DS4104HD = 33,	//4104HD

            DS4002MD_PLUS = 34,    //4002MD+  
            DS4004MD_PLUS = 35,    //4004MD+

            DS4204HFV = 36,	//4204HFV
            DS4308HCV = 37,    //4308HCV
            DS4308HFV = 38,    //4308HFV
            DS4316HCV = 39,    //4316HCV
            DS4316HFV = 40,    //4316HFV
            DS4304HD = 41,    //4304HD
            DS4304HFH = 42,    //4304HFH
            DS4304HFV = 43,    //4304HFV
            DS4302HFH = 44,    //4302HFH
            DS5316HF = 45,    //5316HF
            DS4308HW = 46,    //4308HW
            DS4316HW = 47,    //4316HW
            DS4308MD = 48,    //4308MD
            INVALID_BOARD_TYPE = -1
        }

        public struct DSP_DETAIL
        {
            int encodeChannelCount;			//sum of encode channels in the current DSP
            int firstEncodeChannelIndex;		//the index of the first encode channel of the current DSP
            int decodeChannelCount;			//sum of decode channels in the current DSP
            int firstDecodeChannelIndex;		//the index of the first decode channel of the current DSP
            int displayChannelCount;			//sum of display channels (video output channel) in the current DSP
            int firstDisplayChannelIndex;		//index of the first video output(display) channel of the current DSP
            int reserved1;
            int reserved2;
            int reserved3;
            int initInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }


        public enum VideoStandard_t
        {
            StandardNone = 0,
            StandardNTSC,
            StandardPAL,
            Standard720P_24HZ,
            Standard720P_25HZ,
            Standard720P_30HZ,
            Standard720P_50HZ,
            Standard720P_60HZ,
            Standard1080I_50HZ,
            Standard1080I_60HZ,
            Standard1080P_24HZ,
            Standard1080P_25HZ,
            Standard1080P_30HZ,
            Standard1080P_50HZ,
            Standard1080P_60HZ
        }

        public enum FrameType_t
        {
            PktError = 0,
            PktIFrames = 0x0001,
            PktPFrames = 0x0002,
            PktBBPFrames = 0x0004,
            PktAudioFrames = 0x0008,
            PktMotionDetection = 0x00010,
            PktDspStatus = 0x00020,
            PktOrigImage = 0x00040,
            PktSysHeader = 0x00080,
            PktBPFrames = 0x00100,
            PktSFrames = 0x00200,
            PktSubIFrames = 0x00400,
            PktSubPFrames = 0x00800,
            PktSubBBPFrames = 0x01000,
            PktSubSysHeader = 0x02000
        }


        #endregion

        #region 错误代码
        //        ERR_WAIT_TIMEOUT 0xc0000001 SDK 操作超时
        //ERR_INVALID_HANDLE 0xc0000002 非法句柄，在调用 SDK 函数使用了错误的
        //句柄
        //ERR_INVALID_ARGUMENT 0xc0000003 参数错误，输入的参数可能超出有效范围
        //ERR_DDRAW_CREATE_FAILED 0xc0000004 DDRAW 返回的错误，参见 MSDN
        //ERR_DDRAW_CAPS_FAULT 0xc0000005 DDRAW 返回的错误，参见 MSDN
        //ERR_SET_COOPERATIVELEVEL_FAILED 0xc0000006 DDRAW 返回的错误，参见 MSDN
        //ERR_PRIMARY_SURFACE_CREATE_FAILED 0xc0000007 DDRAW 返回的错误，参见 MSDN
        //ERR_GET_OVERLAY_ADDRESS_FAILED 0xc0000008 DDRAW 返回的错误，参见 MSDN
        //ERR_OVERLAY_SURFACE_CREATE_FAILED 0xc0000009 DDRAW 返回的错误，参见 MSDN
        //ERR_OVERLAY_UPDATE_FAILED 0xc000000a DDRAW 返回的错误，参见 MSDN
        //ERR_TMMAN_FAILURE 0xc000000b SDK 内部错误
        //ERR_CHANNELMAGIC_MISMATCH 0xc000000c 通道数据毁坏
        //ERR_CALLBACK_REGISTERED 0xc000000d 回调函数已注册
        //ERR_QUEUE_OVERFLOW 0xc000000e 数据流缓存溢出
        //ERR__STREAM_THREAD_FAILURE 0xc000000f 无法启动流处理线程
        //ERR_THREAD_STOP_ERROR 0xc0000010 流处理线程停止错误
        //ERR_NOT_SUPPORT 0xc0000011 该功能尚不支持
        //ERR_OUTOF_MEMORY 0xc0000012 系统内存不足
        //ERR_DSP_BUSY 0xc0000013 DSP 正忙
        //ERR_DATA_ERROR(v2.4) 0xc0000014 严重数据错误，必须重新停启压缩
        //ERR_KERNEL 0xc0000016 系统核心错误
        //ERR_OFFSCREEN_CREATE_FAILED 0xc0000017 创建 OFFSCREEN 缓冲区错误
        //ERR_MULTICLOCK_FAILURE 0xc0000018 多媒体时钟错误
        //ERR_INVALID_DEVICE 0xc0000019 无效设备
        //ERR_INVALID_DRIVER 0xc000001a 无效驱动
        //ERR_OFFSCREEN_BLT_FAILED 0xc000001b 不支持画图回调函数
        //ERR_ORDER 0xc000001c 函数调用顺序错误
        //ERR_DDRAW_NONE 0xc000001d 系统错误，没有安装 DDRAW
        //ERR_DDRAW7_UNSUPPORT 0xc000001e 不支持 DDRAW7.0 版本
        //ERR_GLOBAL_OVE_FAILED 0xc000001f 不支持 Overlay
        //ERR_DDRAW_GENERAL 0xc0000020 DirectDraw 一般性错误

        #endregion


        //
        //        返回值： 系统内可用的编码通道个数。
        ///说 明： 初始化系统中每一块板卡，应在应用软件程序启动时完成。如果返回值为 0 则表明初始化失败，
        //可能没有找到相应的 DSP 软件模块。
        /// <summary>
        ///  初始化系统中每一块板卡，应在应用软件程序启动时完成。如果返回值为 0 则表明初始化失败，
        /// </summary>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll", EntryPoint = "InitDSPs")]
        public static extern int InitDSPs();

        //        返回值：  0
        //说 明：  关闭每一块板卡上的功能，应在应用软件程序退出时调用。
        [DllImport("DS40xxSDK.dll")]
        public static extern int DeInitDSPs();

        //返回值：  系统中板卡的总张数。
        //说 明：  获取系统中所有板卡的张数，包含编码卡和解码卡。
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetBoardCount();

        //        返回值：  系统中 DSP 的总个数
        //说 明：  获取系统中所有板卡的 DSP 的个数。
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetDspCount();

        //        返回值：  系统中编码通道的个数
        //说 明：  获取系统中所有编码通道总个数。
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetEncodeChannelCount();

        //        返回值：  系统中解码通道的个数
        //说 明：  获取系统中所有解码通道个数
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetDecodeChannelCount();

        //        返回值：  系统中显示通道的个数
        //说 明：  获取系统中所有显示通道即输出通道的个数。
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetDisplayChannelCount();

        //        返回值：  成功返回 0；失败返回错误号
        //说 明：  获取某张板卡的详细信息
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetBoardDetail(int boardNum, DS_BOARD_DETAIL pBoardDetail);

        //        返回值：  成功返回 0；失败返回错误号
        //说 明：  获取某个 DSP 的详细信息
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetDspDetail(int dspNum, DSP_DETAIL pDspDetail);

        //        返回值：  成功为 0；失败返回错误号
        ///说 明：  获取板卡的型号及序列号信息
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetBoardInfo(IntPtr hChannelHandle, ulong BoardType, string SerialNo);

        #region 编码卡API
        /// <summary>
        /// 返回值：  成功返回有效句柄(值可能为 0)；失败返回 0xFFFFFFFF 或者错误号。
        ///说 明：  打开通道，获取编码通道的操作句柄，与通道相关的操作需使用相对应的句柄。
        /// </summary>
        /// <param name="ChannelNum"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern IntPtr ChannelOpen(int ChannelNum);

        /// <summary>
        /// 返回值：  成功返回 0；失败返回错误号  说 明：  关闭通道，释放相关资源
        /// </summary>
        /// <param name="hChannelHandle">通道句柄</param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int ChannelClose(IntPtr hChannelHandle);

        /// <summary>
        /// 设置视频预览模式 返回值：  
        /// </summary>
        /// <param name="bTrue">BOOL bTrue；是否设置 Overlay 预览方式，也适用于 MD 卡</param>
        /// <returns>0 表示显卡支持板卡的 Overlay 预览方式；其他值表示显卡不支持</returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SetPreviewOverlayMode(bool bTrue);

        /// <summary>
        /// 设置视频预览模式扩展 
        /// </summary>
        /// <param name="bTrue">BOOL bTrue； TRUE， 如果显卡硬件支持则开启全局 Overlay； FALSE，关闭全局 Overlay</param>
        /// <returns>0 表示显卡支持板卡的 Overlay 预览方式；其他值表示显卡不支持</returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SetPreviewOverlayModeEx(bool bTrue);

        /// <summary>
        /// 设置 Overlay 关键色 
        /// </summary>
        /// <param name="DestColorKey">COLORREF DestColorKey； overlay 关键色参数(RGB(*， *， *))</param>
        /// <returns>成功返回 0；失败返回错误号</returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SetOverlayColorKey(Int32 DestColorKey);

        /// <summary>
        /// 恢复当前丢失的表面，例如：当系统按下 CTRL+ALT+DEL 时系统的 OVERLAY 表面会被强制关闭，调用该函数可以恢复 OVERLAY 表面
        /// </summary>
        /// <returns>成功返回 0；失败返回错误号</returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int RestoreOverlay();

        /// <summary>
        /// 启动视频预览，调用 SetPreviewOverlayMode 后，可进行 Overlay 模式预览，否则将默认采用Offscreen 模式预览。
        /// </summary>
        /// <param name="hChannelHandle"></param>
        /// <param name="WndHandle"></param>
        /// <param name="rect">问题已解决了，应该使用IntPtr类型。读取时使用Marshal 类的相关方法。 ref RECT rect</param>
        /// <param name="bOverlay"></param>
        /// <param name="VideoFormat"></param>
        /// <param name="FrameRate"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int StartVideoPreview(IntPtr hChannelHandle, IntPtr WndHandle,
ref RECT rect, bool bOverlay, int VideoFormat, int FrameRate);

        /// <summary>
        /// 停止视频预览
        /// </summary>
        /// <param name="hChannelHandle"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int StopVideoPreview(IntPtr hChannelHandle);

        /// <summary>
        /// 注册编码视频预览画图回调函数
        /// </summary>
        /// <param name="nport"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int RegisterDrawFun(Int32 nport, DRAWFUN drawfun, long nUser);
        public delegate void DRAWFUN(long nPort, IntPtr hDc, long nUser);

        /// <summary>
        /// 停止注册编码视频预览画图回调函数
        /// </summary>
        /// <param name="nport">nport； 通道号。同 RegisterDrawFun 的 nport。</param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int StopRegisterDrawFun(Int32 nport);

        /// <summary>
        /// 抓取固定分辨率的 YUV422 格式原始图像
        /// </summary>
        /// <param name="hChannelHandle">通道句柄</param>
        /// <param name="ImageBuf">原始 yuv422 格式图像指针</param>
        /// <param name="Size">原始 yuv422 格式图像尺寸，函数调用前是 ImageBuf的大小，调用后是实际图像所占用的字节数 DWORD Size = 1920*1080*2;</param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int GetOriginalImage(IntPtr hChannelHandle, byte[] bys, int size);

        /// <summary>
        /// 图像格式转换 YUVtoBMP SaveYUVToBmpFile
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="bys"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SaveYUVToBmpFile(string fileName, byte[] bys, int Width, int Height);

        [DllImport("DS40xxSDK.dll")]
        public static extern int RegisterStreamDirectReadCallback
(STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback, IntPtr Context);

        public delegate int STREAM_DIRECT_READ_CALLBACK(int channelNumber, byte[] DataBuf,
            int Length, int FrameType, IntPtr context);

        /// <summary>
        ///  开启及停止原始数据流捕获
        /// </summary>
        /// <param name="hChannel"></param>
        /// <param name="bStart"></param>
        /// <param name="fps"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="imageBuffer"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SetImageStream(IntPtr hChannel, bool bStart, int fps, int width,
int height, byte[] imageBuffer);

        /// <summary>
        /// 设置系统默认标清视频制式 S
        /// </summary>
        /// <param name="VideoStandard"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SetDefaultVideoStandard(VideoStandard_t VideoStandard);

        /// <summary>
        /// 设置系统默认高清视频制式
        /// </summary>
        /// <param name="VideoStandard"></param>
        /// <returns></returns>
        [DllImport("DS40xxSDK.dll")]
        public static extern int SetDefaultHDVideoStandard(VideoStandard_t VideoStandard);

        [DllImport("DS40xxSDK.dll")]
        public static extern int MotionAnalyzer(IntPtr hChannelHandle, byte[] MotionData, int iThreshold,int[] iResult);

        //[DllImport("DS40xxSDK.dll")]
        //public static extern int DeInitDSPs();

        //[DllImport("DS40xxSDK.dll")]
        //public static extern int DeInitDSPs();



        #endregion
    }

}
